package com.qinglei.recoup.longconn.service.impl;


import com.fasterxml.jackson.databind.JsonNode;
import com.qinglei.recoup.common.domain.CommonConstant;
import com.qinglei.recoup.common.domain.RadarMessage;
import com.qinglei.recoup.common.domain.RadarUserDataDTO;
import com.qinglei.recoup.common.domain.RadarUserDataFour;
import com.qinglei.recoup.common.utils.DateUtil;
import com.qinglei.recoup.common.utils.JsonUtils;
import com.qinglei.recoup.longconn.constant.LongConnConstant;
import com.qinglei.recoup.longconn.entity.Message;
import com.qinglei.recoup.longconn.entity.MessageV4_1;
import com.qinglei.recoup.longconn.entity.UserDataBodyV1;
import com.qinglei.recoup.longconn.entity.UserDataBodyV4_1;
import com.qinglei.recoup.longconn.service.BreathHeartBpmReprocess;
import com.qinglei.recoup.longconn.service.FileService;
import com.qinglei.recoup.longconn.service.RadarDataV4_1Service;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSON;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Slf4j
@Service
public class RadarDataV4_1ServiceImpl implements RadarDataV4_1Service {

    @Autowired
    private FileService fileService;

    @Resource
    RabbitTemplate rabbitTemplate;

    @Value("${spring.rabbitmq.host:}")
    private String rabbitmqHost;

    @Override
    public MessageV4_1 parseHealthCareUserData(String sn, JsonNode itemsNode) {
        UserDataBodyV4_1 userDataBodyV4_1 = new UserDataBodyV4_1();
        userDataBodyV4_1.setTCFg(itemsNode.get("V4:TCFg").get("value").asInt());
        userDataBodyV4_1.setBMPR2(JsonUtils.readDoubleArray(itemsNode.get("V4:BMPR2").get("value")));
        userDataBodyV4_1.setTRaILFg(itemsNode.get("V4:TRaILFg").get("value").asInt());
        userDataBodyV4_1.setHRBpRe(itemsNode.get("V4:HRBpRe").get("value").asInt());
        userDataBodyV4_1.setBPh(JsonUtils.readDoubleArray(itemsNode.get("V4:BPh").get("value")));
        userDataBodyV4_1.setProCode(itemsNode.get("V4:proCode").get("value").asInt());
        userDataBodyV4_1.setBREBP(itemsNode.get("V4:BREBP").get("value").asInt());
        userDataBodyV4_1.setTSFg(itemsNode.get("V4:TSFg").get("value").asInt());
        userDataBodyV4_1.setFrameNo(itemsNode.get("V4:frameNo").get("value").asInt());
        userDataBodyV4_1.setMNoP(format6(itemsNode.get("V4:MNoP").get("value").asDouble()));
        userDataBodyV4_1.setLTRaB(itemsNode.get("V4:LTRaB").get("value").asInt());
        userDataBodyV4_1.setBDEF(format6(itemsNode.get("V4:BDEF").get("value").asDouble()));
        userDataBodyV4_1.setOBAcFg(itemsNode.get("V4:OBAcFg").get("value").asInt());
        userDataBodyV4_1.setSFg(itemsNode.get("V4:SFg").get("value").asInt());
        userDataBodyV4_1.setHBa2(format6(itemsNode.get("V4:HBa2").get("value").asDouble()));
        userDataBodyV4_1.setMH(JsonUtils.readDoubleArray(itemsNode.get("V4:MH").get("value")));
        userDataBodyV4_1.setBPhERaB(itemsNode.get("V4:BPhERaB").get("value").asInt());
        userDataBodyV4_1.setHHm2(format6(itemsNode.get("V4:HHm2").get("value").asDouble()));
        userDataBodyV4_1.setHPhERB(itemsNode.get("V4:HPhERB").get("value").asInt());
        userDataBodyV4_1.setTHRBpEBAg(itemsNode.get("V4:THRBpEBAg").get("value").asInt());
        userDataBodyV4_1.setHS(JsonUtils.readDoubleArray(itemsNode.get("V4:HS").get("value")));
        userDataBodyV4_1.setOBFg2(itemsNode.get("V4:OBFg2").get("value").asInt());
        userDataBodyV4_1.setBS(JsonUtils.readDoubleArray(itemsNode.get("V4:BS").get("value")));
        userDataBodyV4_1.setOBFg(itemsNode.get("V4:OBFg").get("value").asInt());
        userDataBodyV4_1.setOBFg1(itemsNode.get("V4:OBFg1").get("value").asInt());
        userDataBodyV4_1.setBMReFg(JsonUtils.readIntArray(itemsNode.get("V4:BMReFg").get("value")));
        userDataBodyV4_1.setHPh(JsonUtils.readDoubleArray(itemsNode.get("V4:HPh").get("value")));
        userDataBodyV4_1.setAAFg(itemsNode.get("V4:AAFg").get("value").asInt());
        userDataBodyV4_1.setProtocol(itemsNode.get("V4:protocol").get("value").asInt());
        userDataBodyV4_1.setHRBpHmAg(itemsNode.get("V4:HRBpHmAg").get("value").asInt());
        userDataBodyV4_1.setCABS(JsonUtils.readDoubleArray(itemsNode.get("V4:CABS").get("value")));

        MessageV4_1 messageV4_1 = new MessageV4_1();
        messageV4_1.setSn(sn);
        //messageV4_1.setProjectCode(LongConnConstant.PROJECT_CODE_BREATH_HEART);
        messageV4_1.setFuncCode(LongConnConstant.FUNC_UP_USER_DATA);
        messageV4_1.setBody(userDataBodyV4_1);
        Instant instant = Instant.ofEpochMilli(itemsNode.get("V4:frameNo").get("time").asLong());
        LocalDateTime time = LocalDateTime.ofInstant(instant, ZoneOffset.of("+8"));
        messageV4_1.setTimestamp(DateUtil.formatFullTime(time, DateUtil.FULL_TIME_MILLI_BAR_PATTERN));

        return messageV4_1;
    }

    private Map<String, BreathHeartBpmReprocess> HeartBreathBpmReprocess = new HashMap<>();

    @Override
    public void procUploadDataMessageV4_1(MessageV4_1 message) {
        // 处理呼吸心跳数据
        this.procBreathHeartData(message);

        BreathHeartBpmReprocess breathHeartBpmReprocess =  HeartBreathBpmReprocess.get(message.getSn());
        if(breathHeartBpmReprocess==null){
            breathHeartBpmReprocess = new BreathHeartBpmReprocess();
        }
        UserDataBodyV4_1 userDataBodyV41 = message.getBody();

        Map<String,Object> bpmReprocessMap =   breathHeartBpmReprocess.fun_bpm_reprocess(userDataBodyV41.getHRBpHmAg(), userDataBodyV41.getOBFg(),userDataBodyV41.getHRBpRe(),
                userDataBodyV41.getBREBP(),userDataBodyV41.getHHm2());
        HeartBreathBpmReprocess.put(message.getSn(), breathHeartBpmReprocess);
//           log.info("protocolVersion:{} sn:{} => PARAMS>> HRBpHmAg:{}, OBFg:{}, HRBpRe:{}, BREBP: {}, HHm2:{} , RESULT>> HeartBPM:{}, BreathBPM:{}",
//                   "", sn, userDataBodyV41.getHRBpHmAg(), userDataBodyV41.getOBFg(), userDataBodyV41.getHRBpRe(),
//                   userDataBodyV41.getBREBP(), userDataBodyV41.getHHm2(), bpmReprocessMap.get("HeartBPM"), bpmReprocessMap.get("BreathBPM"));

        if(bpmReprocessMap!=null){
            userDataBodyV41.setHRBpRe((int)bpmReprocessMap.get("HeartBPM"));
            userDataBodyV41.setBREBP((int)bpmReprocessMap.get("BreathBPM"));
        }
        message.setBody(userDataBodyV41);

        // 保存文件
        fileService.save(message);
    }

    private void procBreathHeartData(MessageV4_1 message) {
        // 如果是雷达用户数据，发送消息给WEB服务
        if (message.getFuncCode().equals(LongConnConstant.FUNC_UP_USER_DATA)) {
            RadarMessage radarMessage = new RadarMessage();
            radarMessage.setProCode("4_0");  //4.0雷达数据
            radarMessage.setSn(message.getSn());
            radarMessage.setType(RadarMessage.TYPE_USER_DATA);
            UserDataBodyV4_1 userDataBodyV4_1 = new UserDataBodyV4_1();
            BeanUtils.copyProperties(message.getBody(), userDataBodyV4_1);
            RadarUserDataFour radarUserDataFour = new RadarUserDataFour();
            radarUserDataFour.setSn(message.getSn());
            radarUserDataFour.setTSFg(userDataBodyV4_1.getTSFg());
            radarUserDataFour.setOBFg(userDataBodyV4_1.getOBFg());
            radarUserDataFour.setSFg(userDataBodyV4_1.getSFg());
            radarUserDataFour.setTCFg(userDataBodyV4_1.getTCFg());
            radarUserDataFour.setAAFg(userDataBodyV4_1.getAAFg());
            radarUserDataFour.setBrebp(userDataBodyV4_1.getBREBP());
            radarUserDataFour.setHRBpRe(userDataBodyV4_1.getHRBpRe());
            radarUserDataFour.setBs(Arrays.toString(userDataBodyV4_1.getBS()));
            radarUserDataFour.setHs(Arrays.toString(userDataBodyV4_1.getHS()));
            radarUserDataFour.setBdef(userDataBodyV4_1.getBDEF());
            radarUserDataFour.setHPhERB(userDataBodyV4_1.getHPhERB());
            radarUserDataFour.setFrameNo(userDataBodyV4_1.getFrameNo());
            radarUserDataFour.setBMReFg(userDataBodyV4_1.getBMReFg());
            radarUserDataFour.setBMPR2(userDataBodyV4_1.getBMPR2());
            radarMessage.setData(radarUserDataFour);
            LocalDateTime dateTime = LocalDateTime.parse(message.getTimestamp(),
                    DateTimeFormatter.ofPattern(DateUtil.FULL_TIME_MILLI_BAR_PATTERN));
            long milliSecond = dateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
            radarMessage.setTimestamp(milliSecond);
            // 发送消息到MQ
            sendMessage2MQ(radarMessage);
            // 发送消息到大屏MQ队列
            sendMessageDashBoardMQ(radarMessage);
        }
    }

    /**
     * 发送消息到消息队列
     *
     * @param radarMessage
     */
    private void sendMessage2MQ(RadarMessage radarMessage) {
        if (StringUtils.isNotEmpty(rabbitmqHost)) {
            //log.debug("sendMessage2MQ radarMessage: {}", radarMessage);
            rabbitTemplate.convertAndSend(CommonConstant.MQ_RECOUP_DIRECT_EXCHANGE, CommonConstant.MQ_RADAR_DATA_ROUTING, radarMessage);
        }
    }


    /**
     * 发送消息到大屏消息队列
     *
     * @param radarMessage
     */
    private void sendMessageDashBoardMQ(RadarMessage radarMessage) {
        if (StringUtils.isNotEmpty(rabbitmqHost)) {
            rabbitTemplate.convertAndSend(CommonConstant.MQ_DASHBOARD_RECOUP_DIRECT_EXCHANGE,CommonConstant.MQ_RADAR_DATA_TOPIC_ROUTING_KEY, radarMessage
                    ,new CorrelationData(UUID.randomUUID().toString().replaceAll("-","")));
        }
    }

    private static Double format6(double formatDouble){
        return  Double.parseDouble(String.format("%.6f", formatDouble));
    }
}
